package tfsIssueTracker;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import jetbrains.buildServer.serverSide.BuildServerAdapter;
import jetbrains.buildServer.serverSide.BuildServerListener;
import jetbrains.buildServer.util.EventDispatcher;
import jetbrains.buildServer.util.FileUtil;
import jetbrains.buildServer.vcs.VcsException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class TfsExeWrapper
{
  private static final Logger LOG = Logger.getInstance(TfsExeWrapper.class.getName());

  @NonNls
  private static final String ERROR = "Tfs issue tracker support has failed to create utility exe file in the TeamCity server temp folder. Make sure TeamCity server has access to the temp folder: " + System.getProperty("java.io.tmpdir");

  private volatile File myExeFile = null;
  private final List<File> myCreatedFiles = new ArrayList();

    public TfsExeWrapper(@NotNull EventDispatcher<BuildServerListener> server) {
        server.addListener(new BuildServerAdapter() {
            public void serverShutdownComplete() {
                TfsExeWrapper.this.removeFiles();
            }
        });
    }

  private synchronized void removeFiles() {
    this.myExeFile = null;
    for (File createdFile : this.myCreatedFiles) {
      FileUtil.delete(createdFile);
    }
    this.myCreatedFiles.clear();
  }

  private synchronized void copyOut() throws IOException
  {
    if ((!this.myCreatedFiles.isEmpty()) && (this.myExeFile != null) && (this.myExeFile.exists())) return;

    File rootFolder = new File(FileUtil.getTempDirectory(), "TeamCityTfsIssueTracker-" + System.currentTimeMillis());
    this.myCreatedFiles.add(rootFolder);

    if (rootFolder.exists()) {
      FileUtil.delete(rootFolder);
    }

    rootFolder.mkdirs();

    if (!rootFolder.isDirectory()) {
      LOG.warn("File " + this.myExeFile + " already exists. Name was changed");

      copyOut();
      return;
    }

    for (String ext : new String[] { ".exe", ".pdb" }) {
      File file = new File(rootFolder, "TfsWrapper" + ext);
      FileUtil.copyResource(getClass(), "/bin/TfsWrapper" + ext, file);
      if (!file.exists()) {
        throw new FileNotFoundException("Unable to create or copy " + file);
      }
    }

    this.myExeFile = new File(rootFolder, "TfsWrapper.exe");
  }

  private File getExeFileInternal() throws IOException {
    if ((this.myExeFile == null) || (!this.myExeFile.exists())) {
      copyOut();
    }
    return this.myExeFile;
  }

  public synchronized File getExeFile() throws VcsException {
      if (!SystemInfo.isWindows)
          throw new VcsException("Team Foundation Server Issue Tracker Support runs only under Windows");
      try {
          File tfsNative = getExeFileInternal();
          if ((tfsNative == null) || (!tfsNative.isFile())) {
              LOG.debug(ERROR);
              throw new VcsException(ERROR);
          }
          return tfsNative;
      } catch (IOException e) {
          LOG.debug(ERROR, e);
          throw new VcsException(ERROR, e);
      }
  }
}